import BaseScene, { SceneConfig } from '../../components/scenes/BaseScene';
import {
  BoxBufferGeometry,
  BoxGeometry,
  Color,
  Mesh,
  MeshBasicMaterial,
  MeshPhongMaterial,
  PlaneGeometry,
  PointLight,
  SphereBufferGeometry,
} from 'three';
import * as THREE from 'three';

/**
 * 线框的实现思路是：
 * 通过WireframeGeometry转换成线框，之后使用LineSegments进行绘制即可
 */
class BasicScene extends BaseScene {
  constructor(config) {
    super(config);
    const { camera } = this;
    this.addPlane();
    this.addLight();
    this.addWireframeGeometry();
    this.addWireframeGeometry1();
    camera.position.setY(300);
    camera.position.setX(300);
    camera.position.setZ(300);
    camera.lookAt(0, 0, 0);
  }

  private addPlane() {
    const { scene } = this;
    scene.background = new Color(0xaaaaaa);
    const planeGeometry = new PlaneGeometry(1000, 1000);
    const material = new MeshPhongMaterial();
    planeGeometry.rotateX(-Math.PI / 2);
    const boxMesh = new Mesh(planeGeometry, material);
    boxMesh.receiveShadow = true;
    scene.add(boxMesh);
  }
  private addWireframeGeometry() {
    const { scene } = this;
    const geometry = new SphereBufferGeometry(50, 10, 10);
    const wireframe = new THREE.WireframeGeometry(geometry);
    const line = new THREE.LineSegments(wireframe);
    line.position.setY(70);
    line.position.setX(-60);
    line['alphaTest'] = 0.7;
    line.castShadow = true;
    scene.add(line);
  }
  private addWireframeGeometry1() {
    const { scene } = this;
    const geometry = new BoxBufferGeometry(50, 50, 50);
    const wireframe = new THREE.WireframeGeometry(geometry);
    const dashLineMaterial = new THREE.LineDashedMaterial({
      color: 0xffffff,
      scale: 1,
      dashSize: 4,
      gapSize: 2,
    });
    const line = new THREE.LineSegments(wireframe, dashLineMaterial);
    line.position.setY(70);
    line.position.setX(70);
    line.castShadow = true;
    scene.add(line);
  }
  private addLight() {
    const { scene, renderer } = this;
    const light = new PointLight(0xffffff, 0.7);
    light.castShadow = true;
    light.position.setY(300);
    scene.add(light);
    scene.add(new THREE.PointLightHelper(light, 10));
    renderer['shadowMapEnabled'] = true;
  }
}

export const render = (config: SceneConfig): BasicScene => {
  const renderWater = new BasicScene(config);
  renderWater.run();
  return renderWater;
};
